﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Runtime.Serialization;
using System.ServiceModel;
using System.Text;
using OSIRIS.Service.Contracts;

namespace OSIRIS.Service
{
    /// <summary>
    /// The OSIRISService class implements the IOSIRISService interface
    /// to perform the service's functions.
    /// </summary>
    [ServiceBehavior(Namespace = "http://localhost/Services/OSIRIS", Name = "OSIRIS")]
    public class OSIRISService : IOSIRISService
    {
        /// <summary>
        /// Ask OSIRIS for permission if a student is allowed
        /// to start their final internship.
        /// </summary>
        /// <param name="number">The student's number</param>
        /// <returns>True if allowed, false if not</returns>
        public bool AskForPermission(string number)
        {
            /* define the result */
            bool result = false;

            /* if the number is not empty */
            if (number != null)
            {
                /* ask permission from the data layer */
                OSIRISData data = new OSIRISData();
                result = data.AskForPermission(number);
            }
            
            /* return result */
            return result;
        }

        /// <summary>
        /// Fetch the details of a Student.
        /// </summary>
        /// <param name="number">The number of the student</param>
        /// <returns>A filled StudentDetails object</returns>
        public StudentDetails GetStudentDetails(string number)
        {
            /* if the number is not empty */
            if (number != null)
            {
                /* fetch Student from data layer */
                OSIRISData data = new OSIRISData();
                Student student = data.GetStudent(number);

                /* create StudentDetails object */
                StudentDetails details = new StudentDetails();

                /* if the student is not empty */
                if (student != null)
                {
                    /* if the student has an SLB'er */
                    if (student.Teacher1 != null)
                    {
                        /* create and fill TeacherDetails */
                        TeacherDetails slb = new TeacherDetails();
                        slb.Number = student.Teacher1.Number;
                        slb.FirstName = student.Teacher1.FirstName;
                        slb.Prefix = student.Teacher1.Prefix;
                        slb.LastName = student.Teacher1.LastName;
                        slb.Email = student.Teacher1.Email;
                        slb.TelephoneNumber = student.Teacher1.TelephoneNumber;
                        details.Slb = slb;
                    }

                    /* fill StudentDetails */
                    details.Number = student.Number;
                    details.FirstName = student.FirstName;
                    details.Prefix = student.Prefix;
                    details.LastName = student.LastName;
                    details.Email = student.Email;
                    details.TelephoneNumber = student.TelephoneNumber;

                    /* create list for course results and fill it */
                    List<ResultDetails> results = new List<ResultDetails>();
                    foreach (Result foundResult in student.Results)
                    {
                        /* create a new CourseDetails object and fill it */
                        CourseDetails course = new CourseDetails();
                        course.Code = foundResult.Course1.Code;
                        course.Name = foundResult.Course1.Name;

                        /* create a new ResultDetails object and fill it */
                        ResultDetails result = new ResultDetails();
                        result.Course = course;
                        result.Mark = foundResult.Mark;
                        result.Points = foundResult.Points;

                        /* add the result to the list */
                        results.Add(result);
                    }

                    /* create array of results and set them in the details */
                    details.Results = results.ToArray();
                }
                
                /* return the object */
                return details;
            }
            
            /* return empty result */
            return new StudentDetails();
        }

        /// <summary>
        /// Fetch the details of a Teacher.
        /// </summary>
        /// <param name="number">The teacher's number</param>
        /// <returns>A filled TeacherDetails object</returns>
        public TeacherDetails GetTeacherDetails(string number)
        {
            /* if the number is not empty */
            if (number != null)
            {
                /* fetch student from data layer */
                OSIRISData data = new OSIRISData();
                Teacher teacher = data.GetTeacher(number);

                /* create TeacherDetails */
                TeacherDetails details = new TeacherDetails();

                /* if a teacher was found */
                if (teacher != null)
                {
                    /* fill TeacherDetails */
                    details.Number = teacher.Number;
                    details.FirstName = teacher.FirstName;
                    details.Prefix = teacher.Prefix;
                    details.LastName = teacher.LastName;
                    details.Email = teacher.Email;
                    details.TelephoneNumber = teacher.TelephoneNumber;

                    /* create list for student details and fill it */
                    List<StudentDetails> students = new List<StudentDetails>();
                    foreach (Student student in teacher.Students)
                    {
                        /* create StudentDetails and fill it */
                        StudentDetails studentDetails = new StudentDetails();
                        studentDetails.Number = student.Number;
                        studentDetails.FirstName = student.FirstName;
                        studentDetails.Prefix = student.Prefix;
                        studentDetails.LastName = student.LastName;
                        studentDetails.Email = student.Email;
                        studentDetails.TelephoneNumber = student.TelephoneNumber;

                        /* create list for course results */
                        List<ResultDetails> results = new List<ResultDetails>();
                        foreach (Result result in student.Results)
                        {
                            /* create a new CourseDetails object and fill it */
                            CourseDetails course = new CourseDetails();
                            course.Code = result.Course1.Code;
                            course.Name = result.Course1.Name;

                            /* create a new ResultDetails object and fill it */
                            ResultDetails resultDetails = new ResultDetails();
                            resultDetails.Course = course;
                            resultDetails.Mark = result.Mark;
                            resultDetails.Points = result.Points;

                            /* add the ResultDetails to the list */
                            results.Add(resultDetails);
                        }

                        /* create array of results and add them to the StudentDetails */
                        studentDetails.Results = results.ToArray();

                        /* add StudentDetails to the list */
                        students.Add(studentDetails);
                    }

                    /* create an array of the students and add them to the TeacherDetails */
                    details.Students = students.ToArray();
                }

                /* return the result */
                return details;
            }

            /* return default value */
            return new TeacherDetails();
        }
    }
}
